﻿using System;
using System.Collections.Generic;
using System.Linq;
using Nop.Core;
using Nop.Core.Data;
using Nop.Core.Caching;
using Nop.Core.Domain.Advert;
using Nop.Core.Events;


namespace Nop.Services.Advert
{
    public partial class AdvertisementService : IAdvertisementService
    {
        #region Constants
        private const string ADVERTISEMENT_PATTERN_KEY = "Nop.Advertisement.";
        #endregion

        #region Fields

        private readonly IRepository<Advertisement> _advertisementRepository;
        private readonly IEventPublisher _eventPublisher;
        private readonly ICacheManager _cacheManager;
        #endregion

        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="affiliateRepository">Affiliate repository</param>
        /// <param name="eventPublisher">Event published</param>
        public AdvertisementService(IRepository<Advertisement> advertisementRepository,
            IEventPublisher eventPublisher,ICacheManager cachemanager)
        {
            _advertisementRepository = advertisementRepository;
            _eventPublisher = eventPublisher;
            this._cacheManager = cachemanager;
        }

        #endregion

        #region Methods
        public void DeleteAdvertisement(Advertisement Item)
        {
            if (Item == null)
                throw new ArgumentNullException("advertisement");

            Item.Deleted = true;
            UpdateAdvertisement(Item);
        }

        public Advertisement GetAdvertisementById(int Id)
        {
            if (Id == 0)
                return null;

            return _advertisementRepository.GetById(Id);
        }

        public IPagedList<Advertisement> GetAllAdvertisement( DateTime? dateFrom, DateTime? dateTo, int pageIndex, int pageSize, bool showHidden = false)
        {
            var query = _advertisementRepository.Table;
            if (!showHidden)
                query = query.Where(a => a.Published);
             query = query.Where(a => !a.Deleted);
            if(dateFrom!=null&&dateTo!=null)
            {
                query=query.Where(a=>a.StartTime>=dateFrom&&a.EndTime<=dateTo);
            }
            else if(dateFrom!=null)
            {
                query=query.Where(a=>a.StartTime>=dateFrom);
            }
            else if(dateTo!=null)
            {
                 query=query.Where(a=>a.EndTime<=dateTo);
            }
            query = query.OrderBy(a => a.Id);
            var advertisement = new PagedList<Advertisement>(query, pageIndex, pageSize);

            return advertisement;
        }

        public void InsertAdvertisement(Advertisement Item)
        {
            if (Item == null)
                throw new ArgumentNullException("Advertisement");

            _advertisementRepository.Insert(Item);

            //cache
            _cacheManager.RemoveByPattern(ADVERTISEMENT_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityInserted(Item);
        }

        public void UpdateAdvertisement(Advertisement Item)
        {
            if (Item == null)
                throw new ArgumentNullException("Advertisement");

            _advertisementRepository.Update(Item);

            //cache
            _cacheManager.RemoveByPattern(ADVERTISEMENT_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityUpdated(Item);
        }

        public IPagedList<Advertisement> GetNewAdvertisement(int pageSize, int adtype, bool showHidden = false)
        {
            var query = _advertisementRepository.Table;
            if (!showHidden) query = query.Where(a => a.Published);
            query = query.Where(a => !a.Deleted);
            query = query.Where(a => a.AdverType == adtype);
            query = query.Where(a => a.EndTime > DateTime.UtcNow);
            query = query.OrderBy(a => a.StartTime);
            var advertisement = new PagedList<Advertisement>(query, 1, pageSize);

            return advertisement;
        }

        public IList<Advertisement> GetAdvertisement(int pageSize, int adtype, int adlevel, bool showHidden = false)
        {
            var query = _advertisementRepository.Table;
            if (!showHidden) query = query.Where(a => a.Published);

            query = query.Where(a => !a.Deleted);
            query = query.Where(a => a.AdverType == adtype);
            query = query.Where(a => a.AdverLevel == adlevel);
            query = query.Where(a => a.EndTime > DateTime.UtcNow);
            query = query.Where(a => a.StartTime <=DateTime.UtcNow);
            query = query.OrderBy(a => a.StartTime);
            query = query.Take(pageSize);
            return query.ToList(); 
        }

        public IList<Advertisement> GetAdvertisement(int pageSize, int adtype, int adposition, int adlevel, bool showHidden = false)
        {
            var query = _advertisementRepository.Table;
            if (!showHidden) query = query.Where(a => a.Published);

            query = query.Where(a => !a.Deleted);
            query = query.Where(a => a.AdverType == adtype);
            if(adposition>0) query = query.Where(a => a.AdverPosition == adposition);
            if(adlevel>0)    query = query.Where(a => a.AdverLevel == adlevel);
            query = query.Where(a => a.EndTime > DateTime.UtcNow);
            query = query.Where(a => a.StartTime <= DateTime.UtcNow);
            query = query.OrderBy(a => a.StartTime);
            query = query.Take(pageSize);
            return query.OrderBy(r=>r.DisplayOrder).ToList(); 
        }
        #endregion
    }
}
